package com.splic.product.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cmcc.rhsdk.utils.OneKeyLoginRSA;
import lombok.extern.apachecommons.CommonsLog;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;

@CommonsLog
public class OneKeyLoginUtil {
    private static final String chinaMobileUrl = "https://onekey2.cmpassport.com/unisdk/rsapi/loginTokenValidate";

    public static void main(String[] args) throws Exception {
        getChinaMobile("STsid00000016784432922535rg1UE5SeV4AUQw0YQTh1l9xSmqB1NQy", "300002784781");
    }

    public static String getChinaMobile(String token, String cmAppId) throws Exception {
        String privateKeyStr1 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALbUtSAWfK3oPA2kTl3Qv4FjHTCI64Rd4pxyQfO6H0KIRmx9zuJLrwv+pXrLv8tfETGJqE4a54ehvsn7E9K+qCHTezdXXpt51ObLSnEJqlclxLzs0+QPNong7DUiOMQN2tkDSiGDN2M802ruA74VAAF46nsADFUfCIkhkzCmbCGLAgMBAAECgYA2eaRKHkkh7AtQqT8sVtFotOZymqlJ9Etb//NEspUz1rTdCJNG+/P5J/OYZfMMnpPZ5cE/HGcWE4xsVCIw7dvcTwCHkD5j3lTv7GkP0KfkrFctNbNHKzu0mQmMrEiuBvxzaQTAolyTjMWfen/4PTRSBGE5Pr5w5u0RJ+klMaMxUQJBAOmWviRwsvvpgrcn7SK4Ejk2htSZ1rZAtyGev6l/2AAktbALH4RIL2fCClHO1ejrauY+R+Vgn05dsatJhdy5okMCQQDIX0fvMLcs7ZpqTrFzPaksbf4hIpzyxN9czghv/IbLv5/dUa5aKhtqtClgPEPckt/ZVSq6L1OhDVLDLJ0oAYMZAkEA1/wweJVUiiXSXfSnCfFVuF04sqBErmSMcKPO6LVzTj6jWNIQJEpyuufqjtZHaIU1ZQu1gtyisN1liNIE2qEy7QJABeUHsLm2KdQznr0B62n8+BmkSEVEaL/x8kD9bo33STcx9MjaYDys4c67COG8/Vg0zaf7wc5yn2JM9QDy/qJMwQJAKcrJEVqlvVWnHtYNmrXAFGbTuhmMovjwvCZMXDggw/4itH/KvZJe0BGlY8ImAHVDOCZKP8gcrWULglUoOsq3lQ==";
        String privateKeyStr2 = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANdFk2xIokHpBJ7WkMyIAKiNVS0imcy/N6feMOZpR7t1jPSnqH908vkH+h5FkG4Ku+XqrYax7O53G6qzZWS0WTlz+Wvoj/yVgoIuiQuKPCsCrrSZBW6PmnRuq27PE0/nGeftLA1l7/TAWsYCehrWPpWmngWq3uPsCi7Bc3CKvmkRAgMBAAECgYBTvo5ORqdQiqywefoUhyfyaiDjkR1RyGWHWWmeiQBNzboLBxoGk2FePZswoZFBLc3Q8I2W46qvTgimTGm6VmqKt3z/0i6F1CBpBQJSXYz4V8gEmOf34UOVoyZMDFwM49quUiDwpKTfc1KUhuOJ+RG5oCVzKMLEX4cCkWGIha6iLQJBAPC/fOZ1uWabgTzZEkX2VbvkYiwxw5QasY50Kkv7VaUC077AgiUqRiARUUTMSuvByBDe4sBHjxt/BaCNMFAxDdsCQQDk6Oh/7Nso+cTp5uzjHvb6LCZBM8YzpQuOfcjtuuSuPO6t7jO/jpr0FyGQqeXCbRycQKeRfxctys+OpgdIcpaDAkEAr7lVlXIAbeC7qIpZSC/RzF+bON7p/sStLWmlJejCTruNiwJA/Jeqr+V0CF+FoCfFvGqz391bm5pPpSzpQt9LWQJBAOKWSc6XPjlJQ8nkdAg91mu82AEipsboUJAzonjvzv1KA1jXuRGcr3V+kBMKmgvixbdFqJk1HFSPtPSXFA56ntECQQDQCDYb945bCYE/6SeDpM0jR4nTNvDSAyyVDRp1aaMsuiKjOJThFl0tXi3+ulAh2tInz921TGqblXMjhofSbac4";
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOpt("version", "2.0");
        jsonObject.putOpt("msgid", UUID.randomUUID().toString());
        jsonObject.putOpt("systemtime", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN));
        jsonObject.putOpt("strictcheck", "0");
        jsonObject.putOpt("appid", cmAppId);
        jsonObject.putOpt("token", token);
        RSAPrivateKey privateKey = OneKeyLoginRSA.getprivateKeyBykey(privateKeyStr1);
        jsonObject.putOpt("sign", OneKeyLoginRSA.generalSign((cmAppId + token).getBytes(StandardCharsets.UTF_8), privateKey));
        jsonObject.putOpt("encryptionalgorithm", "RSA");
        System.out.println(JSONUtil.toJsonStr(jsonObject));
        String res = HttpRequest.post(chinaMobileUrl)
                .header(Header.CONTENT_TYPE, "application/json")
                .body(JSONUtil.toJsonStr(jsonObject))
                .timeout(20000)
                .execute().body();
        log.info("获取手机号返回" + res);
        JSONObject result = JSONUtil.parseObj(res);
        if ("103000".equals(result.getStr("resultCode"))) {
            return privateKeyDecrypt(result.getStr("msisdn"), privateKeyStr2);
        } else {
            return null;
        }
    }

    /**
     * 私钥签名
     *
     * @param data          appid + token
     * @param privateKeyStr
     * @return 不区分大小写
     */
    public static String sign(byte[] data, String privateKeyStr) {
        Signature signature;
        try {
            RSAPrivateKey privateKey = getprivateKeyBykey(privateKeyStr);
            signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(privateKey);
            signature.update(data);
            return byte2hex(signature.sign());
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * Description：私钥解密
     *
     * @param encodeData 需要解密的数据 hex
     * @return 解密后的数据
     * @author 拜力文
     */
    public static String privateKeyDecrypt(String encodeData, String
            privateKeyStr) {
        Cipher cipher = null;
        try {
            RSAPrivateKey privateKey = getprivateKeyBykey(privateKeyStr);
            byte[] data = hexStr2byte(encodeData);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] output = cipher.doFinal(data);
            return new String(output, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将私钥字符串转换为 RSAPrivateKey 对象
     *
     * @param privatekey 私钥字符串
     * @return RSAPrivateKey 对象
     * @throws Exception 异常
     */
    public static RSAPrivateKey getprivateKeyBykey(String privatekey) throws
            Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] privateKeyByte = Base64.getDecoder().decode(privatekey);
        PKCS8EncodedKeySpec priKeySpec = new
                PKCS8EncodedKeySpec(privateKeyByte);
        RSAPrivateKey privateKey = (RSAPrivateKey)
                keyFactory.generatePrivate(priKeySpec);
        return privateKey;
    }


    /**
     * Description：将二进制转换成 16 进制字符串
     *
     * @param b
     * @return
     * @return String
     * @author name：
     */
    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }


    /**
     * Description：将十六进制的字符串转换成字节数据
     *
     * @param strhex
     * @return
     * @return byte[]
     * @author name：
     */
    public static byte[] hexStr2byte(String strhex) {
        if (strhex == null) {
            return null;
        }
        int l = strhex.length();
        if (l % 2 == 1) {
            return null;
        }
        byte[] b = new byte[l / 2];
        for (int i = 0; i != l / 2; i++) {
            b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2),
                    16);
        }
        return b;
    }
}
